Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] TESTING EXTERNAL SCRIPT: external merge request from Contributor #36476

Closed
wants to merge 20 commits into from

Conversation

AmanAgarwal041
Copy link
Contributor

@AmanAgarwal041 AmanAgarwal041 commented Sep 23, 2024

Description

Fixes #

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11233928007
Commit: 78acdfa
Cypress dashboard.
Tags: @tag.All
Spec:


Tue, 08 Oct 2024 13:08:59 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new RadioButtonControl component for enhanced form functionality, allowing users to select options via radio buttons.
    • Added a new test suite to ensure the reliability of the RadioButtonControl component.
    • Updated the Google Sheets datasource configuration to use radio buttons instead of dropdowns for permissions selection.
  • Bug Fixes

    • Adjusted the layout of the DSEditorWrapper to improve the editor interface.
  • Improvements

    • Repositioned the information banner in the DatasourceForm for better user guidance.
    • Updated the UI for scope options in the DataSources page to reflect the new radio button selection method.

@AmanAgarwal041 AmanAgarwal041 added the ok-to-test Required label for CI label Sep 23, 2024
Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Walkthrough

This pull request introduces a new RadioButtonControl component, enhancing the form controls available in the application. It includes a comprehensive set of unit tests to ensure the functionality of the radio button control. Additionally, the FormControlRegistry is updated to register the new control type, and changes are made to relevant JSON configurations to support this functionality. Other minor modifications involve adjustments to existing components and styles.

Changes

File Change Summary
app/client/src/components/formControls/RadioButtonControl.test.tsx New test file for RadioButtonControl with unit tests for rendering, state updates, and options.
app/client/src/components/formControls/RadioButtonControl.tsx Introduced RadioButtonControl component, extending BaseControl, with dynamic radio button rendering.
app/client/src/pages/Editor/DataSourceEditor/index.tsx Removed height calculation from DSEditorWrapper, affecting its layout.
app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx Repositioned AuthMessage component for Google Sheets datasource creation.
app/client/src/utils/formControl/FormControlRegistry.tsx Added new control type RADIO_BUTTON and registered it in FormControlFactory.
app/client/src/utils/formControl/formControlTypes.ts Added constant RADIO_BUTTON to the exported object for form control types.
app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json Changed control type for datasourceConfiguration.authentication.scopeString from DROP_DOWN to RADIO_BUTTON.
app/client/cypress/support/Pages/DataSources.ts Updated selector for _gsScopeOptions from dropdown to radio group.

Possibly related PRs

Poem

In forms where choices bloom and grow,
A radio button steals the show.
With tests to guard and styles anew,
Our controls are fresh, and functionality too!
Click and select, let options unfold,
A seamless experience, bright and bold! 🌼


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 80d3fc5 and 78acdfa.

📒 Files selected for processing (1)
  • app/client/src/components/formControls/RadioButtonControl.test.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/components/formControls/RadioButtonControl.test.tsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Outside diff range and nitpick comments (3)
app/client/src/components/formControls/RadioButtonControl.tsx (2)

1-24: Class, pay attention! This segment gets an A for structure and implementation.

The imports and class definition are well-organized and follow best practices. The RadioButtonControl class extends BaseControl appropriately, and the render method utilizes redux-form's Field component correctly.

However, to make our code even better, let's consider adding a prop types validation. Can anyone tell me how we might do that?

Consider adding prop types validation using PropTypes or TypeScript interfaces to enhance type safety and documentation.


32-37: Let's give a round of applause for this styled component!

The StyledRadioGroup component is well-defined, using flexbox for layout which is a great practice. The styling provides a clear structure for the radio buttons.

However, class, can anyone suggest how we might make this even more flexible?

Consider using theme variables for colors and spacing to ensure consistency across the application and easier theme customization.

app/client/src/utils/formControl/FormControlRegistry.tsx (1)

188-192: Excellent work on adding the new radio button control!

Your implementation of the RADIO_BUTTON control registration is correct and follows the established pattern. However, to maintain consistency with other control registrations, let's make a small adjustment:

Consider adding a comment above the registration, similar to other controls in this file. For example:

+    // used in [specify where it's used] form
     FormControlFactory.registerControlBuilder(formControlTypes.RADIO_BUTTON, {
       buildPropertyControl(controlProps: RadioButtonControlProps): JSX.Element {
         return <RadioButtonControl {...controlProps} />;
       },
     });

This will help other developers understand where and how this control is used in the application.

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8fe96c9 and 240943f.

Files selected for processing (7)
  • app/client/src/components/formControls/RadioButtonControl.test.tsx (1 hunks)
  • app/client/src/components/formControls/RadioButtonControl.tsx (1 hunks)
  • app/client/src/pages/Editor/DataSourceEditor/index.tsx (0 hunks)
  • app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx (1 hunks)
  • app/client/src/utils/formControl/FormControlRegistry.tsx (2 hunks)
  • app/client/src/utils/formControl/formControlTypes.ts (1 hunks)
  • app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json (1 hunks)
Files not reviewed due to no reviewable changes (1)
  • app/client/src/pages/Editor/DataSourceEditor/index.tsx
Additional comments not posted (9)
app/client/src/utils/formControl/formControlTypes.ts (1)

21-21: Well done, class! A new form control type has been added.

Children, today we've learned about a new addition to our form control family. The RADIO_BUTTON type has joined our classroom of controls. This is an excellent example of how we expand our toolkit to create more interactive and diverse forms.

Let's take a moment to appreciate how neatly it fits in with its classmates. Just like in our classroom, where each of you has a unique name, each control type has its own special identifier. The RADIO_BUTTON follows the same naming convention as its peers, maintaining order and consistency in our code.

Remember, class, in programming as in life, it's important to keep things organized and consistent. This makes it easier for everyone to understand and use our code.

app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json (1)

36-36: Class, let's examine this change in our form configuration!

Now, pay attention to line 36. We've switched our control type from a dropdown menu to radio buttons. This is an excellent choice for presenting permission options!

Why, you ask? Well, radio buttons make all our choices visible at once, which is perfect for important decisions like setting permissions. It's like laying out all your homework options on the desk instead of keeping them hidden in your backpack!

This change will help our users make more informed decisions. Remember, in user interface design, clarity is key!

app/client/src/components/formControls/RadioButtonControl.tsx (2)

26-30: Excellent work on defining types! Gold star for you!

The renderComponentProps type is well-defined, extending RadioButtonControlProps and including additional properties. The use of optional properties (?) provides flexibility in the component's usage.


65-69: Class, let's conclude with the RadioButtonControlProps interface and export statement. They've done their homework!

The RadioButtonControlProps interface is well-defined, extending ControlProps and adding the necessary options property. The export statement correctly makes the RadioButtonControl component available for use in other parts of the application.

Good job! You all get an A for this section.

app/client/src/components/formControls/RadioButtonControl.test.tsx (3)

1-35: Class, let's review our imports and setup!

Well done, students! You've correctly imported all the necessary modules and set up our mock data. This is a great foundation for our test suite. Remember, proper preparation prevents poor performance!


59-80: Now, let's examine our second test, class!

I'm pleased to see you've remembered to check for the default selection. This is crucial in ensuring our radio buttons behave as expected right from the start. You've done an excellent job verifying that only the first option is checked by default.

Keep up the good work, students! This attention to detail will serve you well in your future coding endeavors.


1-110: Class, let's summarize our review!

I'm very pleased with the overall quality of this test file. You've done an excellent job covering the main functionality of our RadioButtonControl component. Your tests are well-structured and address key aspects such as rendering, default selection, and user interaction.

Remember, thorough testing is the foundation of reliable software. The suggestions we've discussed today will help make your tests even more robust. Keep up the great work, and don't forget to apply these principles in your future assignments!

Does anyone have any questions before we conclude our review?

app/client/src/utils/formControl/FormControlRegistry.tsx (1)

38-39: Very good, class! You've added the necessary imports.

The new import statements for RadioButtonControlProps and RadioButtonControl are correctly placed and follow the existing naming conventions. Well done!

app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx (1)

Line range hint 1-690: Well done, class! Let's summarize our lesson for today.

The primary change in this file is the addition of an informative banner for Google Sheets datasource creation. This is a positive improvement that enhances user understanding and transparency.

While the implementation is correct, we've suggested a small refactoring to improve code readability and maintainability. Remember, clear and concise code is easier for your fellow developers to understand and modify in the future.

Keep up the good work, and always strive for clarity in your code!

Comment on lines 39 to 64
function renderComponent(props: renderComponentProps) {
const onChangeHandler = (value: string): any => {
if (typeof props.input?.onChange === "function") {
props.input.onChange(value);
}
};

const options = props.options || [];
const defaultValue = props.initialValue as string;

return (
<StyledRadioGroup
data-testid={props.input?.name}
defaultValue={defaultValue}
onChange={onChangeHandler}
>
{options.map((option) => {
return (
<Radio key={option.value} value={option.value}>
{option.label}
</Radio>
);
})}
</StyledRadioGroup>
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, class, let's examine this renderComponent function. It's doing well, but there's room for improvement!

The function correctly handles the onChange event and maps options to Radio components. The use of defaultValue for setting an initial selection is appropriate.

However, let's think about how we can make this function more robust. Can anyone suggest some improvements?

  1. Add error handling for cases where options are not provided or are empty.
  2. Consider memoizing the Radio components to optimize performance, especially for large option lists.
  3. Add accessibility attributes (aria-label, aria-describedby) to enhance the component's usability for screen readers.

Here's an example of how you might implement these suggestions:

import React, { useMemo } from 'react';

function renderComponent(props: renderComponentProps) {
  const onChangeHandler = (value: string): void => {
    props.input?.onChange?.(value);
  };

  const options = props.options || [];
  const defaultValue = props.initialValue as string;

  if (options.length === 0) {
    console.warn('No options provided for RadioButtonControl');
    return null;
  }

  const memoizedRadios = useMemo(() => 
    options.map((option) => (
      <Radio 
        key={option.value} 
        value={option.value}
        aria-label={option.label}
      >
        {option.label}
      </Radio>
    )),
    [options]
  );

  return (
    <StyledRadioGroup
      data-testid={props.input?.name}
      defaultValue={defaultValue}
      onChange={onChangeHandler}
      aria-label={props.label}
    >
      {memoizedRadios}
    </StyledRadioGroup>
  );
}

Comment on lines 37 to 57
describe("RadioButtonControl", () => {
beforeEach(() => {
let store: any;
store = mockStore();
});
it("should render RadioButtonControl and options properly", async () => {
render(
<Provider store={store}>
<ReduxFormDecorator>
<RadioButtonControl {...radioButtonProps} />
</ReduxFormDecorator>
</Provider>,
);
const radioButton = await waitFor(async () =>
screen.getByTestId("actionConfiguration.testPath"),
);
expect(radioButton).toBeInTheDocument();

const options = screen.getAllByRole("radio");
expect(options).toHaveLength(3);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work on your first test, class!

You've done a splendid job ensuring that our RadioButtonControl renders correctly. Your test checks for the presence of the radio button and verifies the number of options. Bravo!

However, let's challenge ourselves to go a step further. Can anyone tell me how we might improve this test?

Consider adding assertions to check if the labels of the radio buttons match the expected values. This will make our test even more robust! Here's an example of how you could do this:

mockOptions.forEach((option, index) => {
  expect(screen.getByLabelText(option.label)).toBeInTheDocument();
});

Who wants to add this to our test? It'll earn you extra credit!

Comment on lines 82 to 110
it("should select the option when clicked", async () => {
radioButtonProps = {
...radioButtonProps,
};

render(
<Provider store={store}>
<ReduxFormDecorator>
<RadioButtonControl {...radioButtonProps} />
</ReduxFormDecorator>
</Provider>,
);
const radioButton = await waitFor(async () =>
screen.getByTestId("actionConfiguration.testPath"),
);
expect(radioButton).toBeInTheDocument();

const options = screen.getAllByRole("radio");
expect(options[0]).toBeChecked();
expect(options[1]).not.toBeChecked();
expect(options[2]).not.toBeChecked();

options[1].click();

expect(options[0]).not.toBeChecked();
expect(options[1]).toBeChecked();
expect(options[2]).not.toBeChecked();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's review our final test, class!

I'm impressed with your thoroughness in testing the user interaction. You've successfully simulated clicking on a different option and verified that the selection changes accordingly. This is exactly the kind of real-world scenario we want to test!

However, I have a challenge for you to make this test even better. Can anyone guess what it might be?

Let's consider testing all possible selections, not just one. This will ensure our component behaves correctly regardless of which option is chosen. Here's how we could improve this:

mockOptions.forEach((option, index) => {
  options[index].click();
  mockOptions.forEach((_, i) => {
    if (i === index) {
      expect(options[i]).toBeChecked();
    } else {
      expect(options[i]).not.toBeChecked();
    }
  });
});

Who would like to implement this enhancement? It's an excellent opportunity to practice your testing skills!

Comment on lines +680 to +690
{/* This adds information banner when creating google sheets datasource,
this info banner explains why appsmith requires permissions from users google account */}
{datasource && isGoogleSheetPlugin && createFlow ? (
<AuthMessage
actionType={ActionType.DOCUMENTATION}
calloutType="info"
datasource={datasource}
description={googleSheetsInfoMessage}
pageId={pageId}
/>
) : null}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class, pay attention to this important change!

The developer has made a thoughtful modification to improve the user experience when creating a Google Sheets datasource. They've added an informative banner that explains why Appsmith requires permissions from the user's Google account. This is an excellent addition to enhance transparency and user trust.

However, I'd like to see you improve the code's readability. Let's break this down into smaller, more manageable pieces:

-                      {datasource && isGoogleSheetPlugin && createFlow ? (
-                        <AuthMessage
-                          actionType={ActionType.DOCUMENTATION}
-                          calloutType="info"
-                          datasource={datasource}
-                          description={googleSheetsInfoMessage}
-                          pageId={pageId}
-                        />
-                      ) : null}
+                      {renderGoogleSheetsInfoBanner()}

Then, create a new method renderGoogleSheetsInfoBanner:

renderGoogleSheetsInfoBanner() {
  if (this.props.datasource && isGoogleSheetPluginDS(this.props.pluginPackageName) && this.props.createFlow) {
    return (
      <AuthMessage
        actionType={ActionType.DOCUMENTATION}
        calloutType="info"
        datasource={this.props.datasource}
        description={createMessage(GOOGLE_SHEETS_INFO_BANNER_MESSAGE)}
        pageId={this.props.pageId}
      />
    );
  }
  return null;
}

This refactoring will make the render method cleaner and easier to understand. Remember, class, clean code is happy code!

@ayushpahwa ayushpahwa removed their request for review September 25, 2024 05:00
Copy link

Failed server tests

  • com.appsmith.server.imports.internal.ImportServiceTests#importArtifactFromValidJsonFileTest
  • com.appsmith.server.imports.internal.ImportServiceTests#importArtifactIntoWorkspace_pageAddedInBranchApplication_Success
  • com.appsmith.server.imports.internal.ImportServiceTests#importArtifactIntoWorkspace_pageRemovedAndUpdatedDefaultPageNameInBranchApplication_Success

@NilanshBansal NilanshBansal added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Oct 1, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
app/client/cypress/support/Pages/DataSources.ts (2)

197-197: Good job updating the selector, but let's make it even better!

The change from a dropdown to a radio group selector is a step in the right direction. However, to make our code more self-explanatory, we should consider updating the property name to reflect this change.

Consider renaming _gsScopeOptions to _gsScopeRadioGroup to better reflect the new UI component being used. This will make the code more intuitive for other developers:

-  _gsScopeOptions = ".ads-v2-radio-group";
+  _gsScopeRadioGroup = ".ads-v2-radio-group";

Line range hint 1-1097: Class structure could use some spring cleaning!

While the change we've reviewed is good, I couldn't help but notice that this DataSources class is quite large. In the future, we might want to consider breaking it down into smaller, more focused classes. This would make our code easier to maintain and understand, just like how organizing a classroom makes it easier for students to learn!

Consider refactoring this large class into smaller, more focused classes. For example, you could create separate classes for different types of data sources or group related functionalities. This will improve code maintainability and readability in the long run.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 240943f and 5106609.

📒 Files selected for processing (1)
  • app/client/cypress/support/Pages/DataSources.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
app/client/cypress/support/Pages/DataSources.ts (1)

Pattern app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:

  • Follow best practices for Cypress code and e2e automation.
  • Avoid using cy.wait in code.
  • Avoid using cy.pause in code.
  • Avoid using agHelper.sleep().
  • Use locator variables for locators and do not use plain strings.
  • Use data-* attributes for selectors.
  • Avoid Xpaths, Attributes and CSS path.
  • Avoid selectors like .btn.submit or button[type=submit].
  • Perform logins via API with LoginFromAPI.
  • Perform logout via API with LogOutviaAPI.
  • Perform signup via API with SignupFromAPI.
  • Avoid using it.only.
  • Avoid using after and aftereach in test cases.
  • Use multiple assertions for expect statements.
  • Avoid using strings for assertions.
  • Do not use duplicate filenames even with different paths.
  • Avoid using agHelper.Sleep, this.Sleep in any file in code.

Copy link

github-actions bot commented Oct 3, 2024

Failed server tests

  • com.appsmith.server.fork.ApplicationForkingServiceTests#cloneApplicationForkWithConfigurationFalseWithActionsThrice

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (1)
app/client/src/components/formControls/RadioButtonControl.test.tsx (1)

44-61: Good start on your first test, class!

You've done a fine job ensuring that our RadioButtonControl renders correctly. Your test checks for the presence of the radio button and verifies the number of options. Well done!

However, let's challenge ourselves to go a step further. Can anyone tell me how we might improve this test?

Consider adding assertions to check if the labels of the radio buttons match the expected values. This will make our test even more robust! Here's an example of how you could do this:

mockOptions.forEach((option, index) => {
  expect(screen.getByLabelText(option.label)).toBeInTheDocument();
});

Who wants to add this to our test? It'll earn you extra credit!

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5106609 and 80d3fc5.

📒 Files selected for processing (2)
  • app/client/src/components/formControls/RadioButtonControl.test.tsx (1 hunks)
  • app/client/src/components/formControls/RadioButtonControl.tsx (1 hunks)
🧰 Additional context used
🔇 Additional comments (2)
app/client/src/components/formControls/RadioButtonControl.test.tsx (2)

1-35: Excellent work on setting up your test environment, class!

I'm impressed with your thorough preparation. You've imported all the necessary testing libraries and set up a mock store, which is crucial for testing Redux-connected components. Your use of a TestForm component wrapped with reduxForm is a clever way to simulate the real-world usage of our RadioButtonControl.

Keep up the good work! This kind of meticulous setup is the foundation of robust testing.


63-86: Well done on your second test, class!

I'm pleased to see you've thoroughly checked the default state of our RadioButtonControl. You've made sure that the first option is selected by default, and the others are not. This is exactly the kind of attention to detail we need in our tests!

Your use of multiple assertions to check each option's state is commendable. It ensures that our component behaves correctly right from the start.

Keep up the excellent work! This level of thoroughness will serve you well in your future as software engineers.

Comment on lines +88 to +118
it("should select the option when clicked", async () => {
radioButtonProps = {
...radioButtonProps,
};

render(
<Provider store={store}>
<ReduxFormDecorator>
<RadioButtonControl {...radioButtonProps} />
</ReduxFormDecorator>
</Provider>,
);
const radioButton = (await screen.findByTestId(
"actionConfiguration.testPath",
)) as HTMLElement;

expect(radioButton).toBeInTheDocument();

const options = screen.getAllByRole("radio");

expect(options[0]).toBeChecked();
expect(options[1]).not.toBeChecked();
expect(options[2]).not.toBeChecked();

options[1].click();

expect(options[0]).not.toBeChecked();
expect(options[1]).toBeChecked();
expect(options[2]).not.toBeChecked();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Let's review our final test, class!

I'm impressed with your thoroughness in testing the user interaction. You've successfully simulated clicking on a different option and verified that the selection changes accordingly. This is exactly the kind of real-world scenario we want to test!

However, I have a challenge for you to make this test even better. Can anyone guess what it might be?

Let's consider testing all possible selections, not just one. This will ensure our component behaves correctly regardless of which option is chosen. Here's how we could improve this:

mockOptions.forEach((option, index) => {
  options[index].click();
  mockOptions.forEach((_, i) => {
    if (i === index) {
      expect(options[i]).toBeChecked();
    } else {
      expect(options[i]).not.toBeChecked();
    }
  });
});

Who would like to implement this enhancement? It's an excellent opportunity to practice your testing skills!

Comment on lines +16 to +21
<Field
component={renderComponent}
name={this.props.configProperty}
props={{ ...this.props }}
type="radiobutton"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the way props are passed to the Field component

Class, let's pay attention to how we're passing props to the Field component from redux-form. Currently, we're nesting our control's props under a props key by using props={{ ...this.props }}. This might cause issues when accessing props in renderComponent. Instead, we should spread this.props directly into the Field component so that they are passed correctly.

Apply this diff to fix the issue:

 <Field
    component={renderComponent}
    name={this.props.configProperty}
-   props={{ ...this.props }}
+   {...this.props}
    type="radiobutton"
 />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Field
component={renderComponent}
name={this.props.configProperty}
props={{ ...this.props }}
type="radiobutton"
/>
<Field
component={renderComponent}
name={this.props.configProperty}
{...this.props}
type="radiobutton"
/>

Comment on lines +47 to +53
const defaultValue = props.initialValue as string;

return (
<StyledRadioGroup
data-testid={props.input?.name}
defaultValue={defaultValue}
onChange={onChangeHandler}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Make the RadioGroup a controlled component by using value instead of defaultValue

Class, to ensure that our RadioGroup stays in sync with the form state managed by redux-form, we should use value instead of defaultValue, and assign it to props.input?.value. This makes the RadioGroup a controlled component, which is essential for proper form behavior.

Apply this diff to make the component controlled:

- const defaultValue = props.initialValue as string;

 return (
   <StyledRadioGroup
     data-testid={props.input?.name}
-    defaultValue={defaultValue}
+    value={props.input?.value as string}
     onChange={onChangeHandler}
   >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const defaultValue = props.initialValue as string;
return (
<StyledRadioGroup
data-testid={props.input?.name}
defaultValue={defaultValue}
onChange={onChangeHandler}
return (
<StyledRadioGroup
data-testid={props.input?.name}
value={props.input?.value as string}
onChange={onChangeHandler}

Comment on lines +26 to +30
type renderComponentProps = RadioButtonControlProps & {
input?: WrappedFieldInputProps;
meta?: WrappedFieldMetaProps;
options?: Array<{ label: string; value: string }>;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure type consistency for the options property

Class, let's make sure we're maintaining consistency in our type definitions. The options property in renderComponentProps is currently defined as optional and uses an inline type. However, in RadioButtonControlProps, it's defined as required and uses SelectOptionProps[]. To avoid confusion and improve maintainability, we should use SelectOptionProps[] in both places and ensure options is consistently treated as required or optional.

Apply this diff to align the types:

 type renderComponentProps = RadioButtonControlProps & {
   input?: WrappedFieldInputProps;
   meta?: WrappedFieldMetaProps;
-  options?: Array<{ label: string; value: string }>;
 };

Committable suggestion was skipped due to low confidence.

@NilanshBansal NilanshBansal changed the title TESTING EXTERNAL SCRIPT: external merge request from Contributor [DO NOT MERGE] TESTING EXTERNAL SCRIPT: external merge request from Contributor Oct 9, 2024
@NilanshBansal
Copy link
Contributor

Closing as the original PR #35985 is merged

@NilanshBansal NilanshBansal deleted the chore/external-contribution-35985 branch October 9, 2024 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants